from socket import *
import select
import re
import gexin

rowo = ''


def Service():
    service_sock = socket(AF_INET, SOCK_STREAM)
    service_sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
    service_sock.bind(('', 8080))
    service_sock.listen(128)
    service_sock.setblocking(False)

    # 创建个epoll对象
    myepoll = select.epoll()
    myepoll.register(service_sock.fileno(), select.EPOLLIN)  # EPOLLIN读事件

    client_name = dict()
    client_event = dict()
    while True:
        epoll_list = myepoll.poll()  # poll返回一个列表,每个元素是个元组,每个元组中包含文件描述符和事件
        for fd, event in epoll_list:
            if fd == service_sock.fileno():
                client_data, addr = service_sock.accept()
                print('%s连接了' % str(addr))
                client_data.setblocking(False)
                client_name[client_data.fileno()] = client_data  # 存储套接字,键是当前套接字的文件描述符
                client_event[client_data.fileno()] = addr
                myepoll.register(client_data.fileno(), select.EPOLLIN | select.EPOLLET | select.EPOLLOUT)
            elif event & select.EPOLLIN:
                while True:
                    try:
                        data = client_name[fd].recv(4096)
                    except:
                        break
                    else:
                        if data:
                            data_all = data.decode()
                            info = re.match(r'\w+\s+(\S+)', data_all).group(1)
                            print(info)
                            if info == '/':
                                info = '/index.html'
                            env = {'name': info}
                            if re.search('\.py', info):
                                body = gexin.app(env, func)
                                x = (rowo + body).encode()
                                client_name[fd].send(x)
                                client_name[fd].close()
                            else:
                                try:
                                    file = open('../2017-10-6' + info, 'rb')
                                except Exception as e:
                                    body = str(type(e)).encode()
                                    heard = 'Http/1.1 404 Not Found\r\n'
                                    row = (heard + 'Service: WJY\r\n\r\n').encode() + body
                                else:
                                    heard = 'Http/1.1 200 OK\r\n'
                                    body = file.read()
                                    file.close()
                                    row = (heard + 'Service: MyWeb\r\n\r\n').encode() + body
                                finally:
                                    send_len = len(row)
                                    begin_len = 0
                                    while begin_len < send_len:
                                        try:
                                            begin_len += client_name[fd].send(row[begin_len:begin_len + 1024])
                                            print(begin_len)
                                        except:
                                            pass
                                    client_name[fd].close()

                        else:
                            print('%s离开了' % str(client_event[fd]))
                            client_name[fd].close()
                            myepoll.unregister(fd)
                            del client_name[fd]
                            del client_event[fd]


def func(stat, heard):
    global rowo
    link = 'Http/1.1 ' + stat + '\r\n'
    heards = ''
    for i, n in heard:
        heards = i + n + '\r\n'
    rowo = link + heards + 'Content-Type:text/html; charset=utf-8\r\n\r\n'


if __name__ == '__main__':
    Service()
